package workflowminer.load;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.List;
import java.util.Vector;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

import workflowminer.domain.Role;
import workflowminer.domain.VarData;
import workflowminer.interfaces.AuditTrailEntry;
import workflowminer.interfaces.ProcessInstance;
import workflowminer.interfaces.WorkflowLog;

public class WorkflowLoader {
	
	private String eventType="EventType";
	private String originator="Originator";
	private String timeStamp="TimeStamp";
	private String workflowModelElement="WorkflowModelElement";
	
	private Vector<VarData> eventTypes = new Vector<VarData>();
	private Vector<VarData> originators = new Vector<VarData>();
	private Vector<VarData> timestamps = new Vector<VarData>();
	private Vector<VarData> wfelements = new Vector<VarData>();
	
	private ChartGenerator chartGenerator;
	
	public List<ProcessInstance> getInstances() {
		return instances;
	}

	private List<ProcessInstance> instances;
	private Vector<String> users;
	
	public WorkflowLoader() throws JAXBException, FileNotFoundException{
		this.chartGenerator = new ChartGenerator("grafico.jpg");
	}
	
	public void loadWorkFlow(String path){
		eventTypes = new Vector<VarData>();
		originators = new Vector<VarData>();
		timestamps = new Vector<VarData>();
		wfelements = new Vector<VarData>();
		JAXBContext context;
		try {
		try {
			context = JAXBContext.newInstance("workflowminer.interfaces");
			Unmarshaller unmarshaller = context.createUnmarshaller(); 
			WorkflowLog process = (WorkflowLog) unmarshaller.unmarshal(new FileInputStream(path));
			this.instances = process.getProcess().getProcessInstance();
			this.loadVariables(process.getProcess().getProcessInstance());
		} catch (JAXBException e1) {
			e1.printStackTrace();
		}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} 
	}
	
	public void loadVariables(List<ProcessInstance> name){
		this.users = new Vector<String>();
		for (ProcessInstance instance : name) {
			for (AuditTrailEntry entry :  instance.getAuditTrailEntry()){
				this.addOcurrency(eventTypes, entry.getEventType(),eventType);
				this.addOcurrency(originators, entry.getOriginator(),originator);
				if (!users.contains(entry.getOriginator())){
					users.add(entry.getOriginator());
				}
				this.addOcurrency(timestamps, entry.getTimestamp().toString(),timeStamp);
				this.addOcurrency(wfelements, entry.getWorkflowModelElement(),workflowModelElement);
			}
		}		
	}
	
	public Vector<VarData> getEventTypes() {
		return eventTypes;
	}

	public Vector<VarData> getOriginators() {
		return originators;
	}

	public Vector<VarData> getTimestamps() {
		return timestamps;
	}

	public Vector<VarData> getWfelements() {
		return wfelements;
	}

	public void addOcurrency(Vector<VarData> vector,String value,String name){
		for (VarData data : vector) {
			if (data.getValue().equals(value)){
				data.setOcurrencies(data.getOcurrencies()+1);
				return;
			}
		}
		VarData newData = new VarData(name,value);
		vector.add(newData);
	}

	public ChartGenerator getChartGenerator() {
		return chartGenerator;
	}

	public String[] getAllVariables() {
		String[] vars = {this.eventType,this.originator,this.workflowModelElement};
		return vars;
	}

	public Vector<VarData> getVariable(String variable) {
		if (variable.equals(this.eventType))  return eventTypes; 
		if (variable.equals(this.originator))  return originators; 
		if (variable.equals(this.timeStamp)) return timestamps; 
		if (variable.equals(this.workflowModelElement)) return wfelements;
		return null; 
	}

	public Vector<Role> getRoles() {
		ClusterAlgorithm ca = new ClusterAlgorithm(users,this.instances);
		Vector<Role> roles = ca.generateRolesFastMiner();
		return roles;
	}
	
	
}
